package com.xyht.medicine_management_system.modules.payment.wxpay.util;

import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.app.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.profitsharing.model.OrdersEntity;
import com.wechat.pay.java.service.profitsharing.model.QueryOrderRequest;
import com.wechat.pay.java.service.profitsharing.model.UnfreezeOrderRequest;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.QueryByOutRefundNoRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import com.xyht.medicine_management_system.common.util.TimeUtil;
import com.xyht.medicine_management_system.modules.payment.wxpay.config.WxPayConfig;
import com.xyht.medicine_management_system.modules.payment.wxpay.entity.CallbackPayResourceEntity;
import com.xyht.medicine_management_system.modules.payment.wxpay.entity.PrepayPaymentReq;
import com.xyht.medicine_management_system.modules.payment.wxpay.entity.RefundReq;
import com.xyht.medicine_management_system.modules.wx.entity.WxMpPropertiesEntity;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import static com.xyht.medicine_management_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.medicine_management_system.modules.payment.constant.CommonConstant.WX_MERCHANT_ID;
import static com.xyht.medicine_management_system.modules.payment.constant.CommonConstant.WX_NOTIFY_PAY_CALLBACK;

@Component
public class WxPayUtil {
    @Resource
    private WxMpPropertiesEntity wxMpPropertiesEntity;

    /**
     * @description 订单预支付 生成预支付码给前端
     * @create 2023/12/21
     * @author dxn
     */
    public String prepayPayment(PrepayPaymentReq prepayPaymentReq) {
        if (isNullOrEmpty(prepayPaymentReq.getOutTradeNo(), prepayPaymentReq.getDescription(),
                prepayPaymentReq.getTimeExpire(), prepayPaymentReq.getTotal())) {
            return null;
        }
        PrepayRequest request = new PrepayRequest();
        request.setAppid(wxMpPropertiesEntity.getAppId());
        request.setMchid(WX_MERCHANT_ID);
        request.setDescription(prepayPaymentReq.getDescription());
        request.setTimeExpire(TimeUtil.WXDateformat(prepayPaymentReq.getTimeExpire()));
        request.setNotifyUrl(WX_NOTIFY_PAY_CALLBACK);

        Amount amount = new Amount();
        amount.setTotal(prepayPaymentReq.getTotal());
        request.setAmount(amount);

        SettleInfo settleInfo = new SettleInfo();
        settleInfo.setProfitSharing(true);
        request.setSettleInfo(settleInfo);

        PrepayWithRequestPaymentResponse response = WxPayConfig.appServiceExtension.prepayWithRequestPayment(request);
        if (isNullOrEmpty(response.getPrepayId())) {
            return null;
        }
        return response.getPrepayId();
    }


    /**
     * @param order_id 订单号
     * @description 订单状态查询
     * @create 2023/12/24
     * @author dxn
     */
    public Transaction queryOrderByOutTradeNo(String order_id) {
        QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
        request.setMchid(WX_MERCHANT_ID);
        request.setOutTradeNo(order_id);
        return WxPayConfig.appServiceExtension.queryOrderByOutTradeNo(request);
    }

    /**
     * @description 校验并解析微信回调通知
     * @create 2023/12/24
     * @author dxn
     */
    public CallbackPayResourceEntity checkNotificationSign(RequestParam requestParam) {
        CallbackPayResourceEntity resourceEntity;
        try {
            resourceEntity = WxPayConfig.notificationParser.parse(requestParam, CallbackPayResourceEntity.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return resourceEntity;
    }

    /**
     * @description 用户退款
     * @create 2023/12/24
     * @author dxn
     */
    public Refund createRefund(RefundReq refundReq) {
        CreateRequest request = new CreateRequest();
        // 调用request.setXxx(val)设置所需参数，具体参数可见Request定义
        // 调用接口
        request.setSubMchid(WX_MERCHANT_ID);
        request.setTransactionId(refundReq.getTransaction_id());
        request.setOutTradeNo(refundReq.getOut_trade_no());
        request.setOutRefundNo(refundReq.getOut_refund_no());
        request.setReason(refundReq.getReason());
        request.setNotifyUrl(WX_NOTIFY_PAY_CALLBACK);

        AmountReq amount = new AmountReq();
        amount.setRefund(refundReq.getRefund());
        amount.setTotal(refundReq.getTotal());
        request.setAmount(amount);

        return WxPayConfig.refundService.create(request);
    }

    /**
     * @param refund_id 退款单号
     * @description 用户退款查询
     * @create 2023/12/25
     * @author dxn
     */
    public Refund queryByOutRefundNo(String refund_id) {
        QueryByOutRefundNoRequest request = new QueryByOutRefundNoRequest();
        request.setSubMchid(WX_MERCHANT_ID);
        request.setOutRefundNo(refund_id);
        return WxPayConfig.refundService.queryByOutRefundNo(request);
    }

    /**
     * @param order_id       订单号
     * @param transaction_id 微信订单号
     * @description 分账完结解除冻结
     * @create 2023/12/25
     * @author dxn
     */
    public OrdersEntity profitSharingUnfreezeOrder(String order_id, String transaction_id) {
        UnfreezeOrderRequest request = new UnfreezeOrderRequest();
        request.setNotifyUrl(WX_NOTIFY_PAY_CALLBACK);
        request.setOutOrderNo(order_id);
        request.setTransactionId(transaction_id);
        request.setSubMchid(WX_MERCHANT_ID);
        return WxPayConfig.profitsharingService.unfreezeOrder(request);
    }

    /**
     * @param order_id       订单号
     * @param transaction_id 微信订单号
     * @description 分账结果查询
     * @create 2023/12/25
     * @author dxn
     */
    public OrdersEntity profitSharingQueryOrder(String order_id, String transaction_id) {
        QueryOrderRequest request = new QueryOrderRequest();
        request.setSubMchid(WX_MERCHANT_ID);
        request.setOutOrderNo(order_id);
        request.setTransactionId(transaction_id);
        return WxPayConfig.profitsharingService.queryOrder(request);
    }


}
